import { defineStore } from 'pinia';
import { pinia } from '@shared/internal/pinia';
import type { UserSignProperties } from '#common/types/user';
import type { UserSettingsProperties } from '#common/types/settings';
import type { ClientAppLoginReq } from '@/shared/service/auth';
import { clientUserDataStore, clientUserSettings } from '@shared/internal/client';
import type { ClientAppLogin } from './types/user';
import { socketConnect } from '@view/main/socket';
import { router } from '@main/router';
import { logoutShowLoginWindow } from '@main/utils/window';
import { socketDestroy } from '@main/socket';
import { businesseStorageShortName } from '../utils/env';
import { clientAppLoginApi, refreshTokenApi, isTokenExpired } from '@/shared/service/auth';
import { useWorkflowStoreWithOut } from '@main/store/workflow';

interface UserState {
  userData?: Nullable<UserSignProperties>;
  userSetting?: Nullable<UserSettingsProperties>;
}

const loginAccountKey = businesseStorageShortName('loginAccount');

export const useUserStore = defineStore('userStore', {
  state: (): UserState => ({
    userData: null,
    userSetting: null
  }),
  getters: {
    getTokenData(state) {
      if (!state.userData) {
        return;
      }
      return state.userData.tokenData;
    },
    getUser(state) {
      if (!state.userData) {
        return;
      }
      return state.userData.user;
    }
  },
  actions: {
    async userLoginAction(reqData: ClientAppLogin) {
      try {
        //登录
        const { data, headers } = await clientAppLoginApi(reqData as ClientAppLoginReq);
        //组装数据
        const userData = {
          user: data.data,
          tokenData: {
            access_token: headers['access-token'],
            refresh_token: headers['x-access-token']
          },
          autoLogin: reqData.autoLogin
        };
        //存入仓储
        this.setUserDataAction(userData);
        //存入本地
        await this.setClientUserDataStoreAction(userData);
        //初始化用户设置
        const userSetting = await clientUserSettings.get('userSettings');
        if (userSetting) this.userSetting = userSetting as UserSettingsProperties;
        //连接socket
        await socketConnect();
        //初始化任务
        useWorkflowStoreWithOut().initHistoryContentArray();
        return Promise.resolve();
      } catch (error) {
        console.error('userLoginAction', error);
        //清除本地数据
        await clientUserDataStore.clear();
        return Promise.reject();
      }
    },
    // 退出登录
    async logoutAction() {
      if (!this.userData) {
        return;
      }
      try {
        //退出登录
        logoutShowLoginWindow(300, async () => {
          //断开socket
          await socketDestroy();
          //清除本地数据
          clientUserDataStore.clear();
          //重置仓储
          await this.resetStoreAction();
          //跳转登录
          return router.replace({ name: 'Login' }).catch((error) => {
            console.error('to login error >>>', error);
          });
        });
      } catch (error) {
        console.error('logoutAction', error);
      }
    },
    async getEfficaciousToken() {
      if (!this.userData) {
        return;
      }

      //token过期
      if (!isTokenExpired(this.userData.tokenData.access_token)) return this.userData.tokenData;

      try {
        //刷新token
        const { headers } = await refreshTokenApi();
        if (headers['access-token'] && headers['x-access-token']) {
          //组装数据
          const userData = Object.assign({}, this.userData, {
            tokenData: {
              access_token: headers['access-token'],
              refresh_token: headers['x-access-token']
            }
          });
          //存入仓储
          this.setUserDataAction(userData);
          //存入本地
          await this.setClientUserDataStoreAction(userData);
          //组装数据
          userData.tokenData.access_token = headers['access-token'];
          //退出登录
          this.logoutAction();
        }
      } catch (error) {
        console.error('刷新过期Token失败', error);
      }
      return this.userData.tokenData;
    },
    async setUserSettingAction(newUserSettings: Partial<UserSettingsProperties>) {
      try {
        //存入本地
        await clientUserSettings.set('userSettings', { ...this.userSetting, ...newUserSettings });
        return Promise.resolve();
      } catch (error) {
        console.error('setUserSettingAction', error);
        //清除本地数据
        await clientUserSettings.clear();
        return Promise.reject();
      }
    },
    setUserDataAction(data: UserSignProperties) {
      this.userData = data;
    },
    async setClientUserDataStoreAction(userData: UserSignProperties) {
      await clientUserDataStore.set({ ...userData });
    },
    async setAutoLoginAction(autoLogin: boolean) {
      const persistLoginAccountData = this.getLocalPersistLoginAccountData();
      this.saveLocalPersistLoginAccountData(
        Object.assign({}, persistLoginAccountData, { autoLogin })
      );
    },
    async resetStoreAction() {
      this.userData = null;
      await this.setAutoLoginAction(false);
    },
    getLocalPersistLoginAccountData() {
      try {
        const data = localStorage.getItem(loginAccountKey);
        if (!data) {
          return;
        }
        return JSON.parse(data) as ClientAppLogin;
      } catch (error) {
        console.error('getLocalPersistLoginAccountData error >>>', error);
      }
    },
    saveLocalPersistLoginAccountData(data: ClientAppLogin) {
      if (!data) {
        return;
      }
      try {
        localStorage.setItem(loginAccountKey, JSON.stringify(data));
      } catch (error) {
        console.error('saveLocalPersistLoginAccountData error >>>', error);
      }
    },
    clearLocalPersistData() {
      localStorage.removeItem(loginAccountKey);
    }
  }
});

export function useUserStoreWithOut() {
  return useUserStore(pinia);
}
